package com.cby.android.sample.activities

import android.graphics.Bitmap
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import com.cby.android.library.base.BaseStateActivity
import com.cby.android.library.base.callback.EmptyCallback
import com.cby.android.library.base.callback.ErrorCallback
import com.cby.android.library.base.callback.LoadingCallback
import com.cby.android.library.base.callback.TimeoutCallback
import com.cby.android.library.ext.observe
import com.cby.android.sample.R
import com.cby.android.sample.adapter.binder.WeatherLaterItemBinder
import com.cby.android.sample.constant.Constant
import com.cby.android.sample.intent.WeatherIntent
import com.cby.android.sample.model.WeatherViewModel
import com.cby.android.sample.state.WeatherState
import com.chad.library.adapter.base.BaseBinderAdapter
import com.gyf.immersionbar.ImmersionBar
import com.cby.android.sample.adapter.binder.WeatherCalendarItemBinder
import com.cby.android.sample.adapter.binder.WeatherHeaderItemBinder
import com.cby.android.sample.adapter.binder.WeatherSuggestionItemBinder
import com.kingja.loadsir.core.LoadSir
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import jp.wasabeef.blurry.Blurry
import kotlinx.coroutines.launch

/**
 * @description: WeatherActivity
 *
 * @author ChenBaoyang
 * @date 4/27/21 11:30
 */
class WeatherActivity : BaseStateActivity<WeatherViewModel, WeatherState, WeatherIntent>() {

    private val bgIv: ImageView by lazy { findViewById(R.id.iv_bg) }
    private val bgIv2: ImageView by lazy { findViewById(R.id.iv_bg2) }
    private val bgBlurLl: LinearLayout by lazy { findViewById(R.id.ll_bg_blur) }

    private val backRl: RelativeLayout by lazy { findViewById(R.id.rl_back) }
    private val titleTv: TextView by lazy { findViewById(R.id.tv_title) }
    private val contentLl: LinearLayout by lazy { findViewById(R.id.ll_content) }

    private val refreshLayout: SmartRefreshLayout by lazy { findViewById(R.id.refreshLayout) }
    private val recyclerView: RecyclerView by lazy { findViewById(R.id.recycler_view) }

    private lateinit var provinceName: String
    private lateinit var cityName: String
    private lateinit var location: String

    private val defaultAlpha = 0.0f
    private val maxAlpha = 1.0f

    private val adapter = BaseBinderAdapter()

    override fun bindLiveData() {
        observe(viewModel!!.state) {
            adapter.setList(it.data)
            refreshLayout.finishRefresh(true)
        }

    }

    override fun parseArgs() {
        provinceName = intent.getStringExtra(Constant.KEY_PROVINCE_NAME)?: "福建省"
        cityName = intent.getStringExtra(Constant.KEY_CITY_NAME) ?: "厦门市"
        location = intent.getStringExtra(Constant.KEY_LOCATION).toString()
    }

    override fun onViewInit() {
        titleTv.text = "$provinceName-$cityName"

        initItemBinder()
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter
        recyclerView.itemAnimator = DefaultItemAnimator()
        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            private var totalDy = 0
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                val height = recyclerView.height
                totalDy -= dy
                var alpha: Float =
                    Math.abs(totalDy) * maxAlpha / 700
                if (alpha > maxAlpha) {
                    alpha = maxAlpha
                }
                if (alpha < defaultAlpha) {
                    alpha = defaultAlpha
                }
                bgBlurLl.alpha = alpha
            }
        })

        backRl.setOnClickListener {
            finish()
        }

        refreshLayout.setOnRefreshListener {
            onDataInit()
        }
        refreshLayout.setEnableLoadMore(false)

        initBackground()

        ImmersionBar.with(this).titleBar(contentLl).transparentStatusBar().init()
    }

    private fun initBackground() {
        val options = RequestOptions()
        options.centerCrop()
        Glide.with(this@WeatherActivity)
            .asBitmap()
            .load(Constant.DEFAULT_IMAGE_URL)
            .apply(options)
            .into(object : SimpleTarget<Bitmap?>() {
                override fun onResourceReady(
                    resource: Bitmap,
                    transition: Transition<in Bitmap?>?
                ) {
                    bgIv.setImageBitmap(resource)
                    bgIv2.setImageBitmap(resource)
                    Blurry.with(this@WeatherActivity)
                        .radius(25)
                        .sampling(3)
                        .async()
                        .capture(bgIv2)
                        .into(bgIv2)
                    bgBlurLl.alpha = defaultAlpha
                }
            })
    }

    private fun initItemBinder() {
        adapter.addItemBinder(WeatherHeaderItemBinder())
            .addItemBinder(WeatherLaterItemBinder())
            .addItemBinder(WeatherSuggestionItemBinder())
            .addItemBinder(WeatherCalendarItemBinder())
    }

    override fun initLoadSir() {
        val loadSir = LoadSir.Builder()
            .addCallback(LoadingCallback())
            .addCallback(EmptyCallback())
            .addCallback(ErrorCallback())
            .addCallback(TimeoutCallback())
            .build()
        loadService = loadSir.register(getTargetView()) {
            reload()
        }
    }

    override fun pageLoading() {
        if(adapter.itemCount <= 0) {
            loadService?.showCallback(LoadingCallback::class.java)
        }
    }

    override fun reload() {
        lifecycleScope.launch {
            viewModel!!.intents.send(WeatherIntent.LoadWeather(location, cityName))
        }
    }

    override fun getLayoutId() = R.layout.activity_weather

    override fun onDataInit() {
        super.onDataInit()
        reload()
    }

    override fun getTargetView() = refreshLayout
}